package com.beans;

import java.io.Serializable;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.ComponentSystemEvent;
import javax.inject.Inject;
import javax.inject.Named;

import org.primefaces.component.datatable.DataTable;
import org.primefaces.component.selectonemenu.SelectOneMenu;
import org.primefaces.context.RequestContext;
import org.primefaces.event.SelectEvent;
import org.primefaces.event.UnselectEvent;
import org.springframework.context.annotation.Scope;

import com.controllers.CommentController;
import com.controllers.EmailController;
import com.controllers.EmployeeController;
import com.controllers.TaskController;
import com.model.Activity;
import com.model.Comment;
import com.model.Employee;
import com.model.Task;

@Named
@Scope(value = "session")
public class TasksTableBean implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -8247873848403504737L;

	private Task myTask;

	private TaskController taskController;

	private List<Activity> activities;

	public static List<Activity> allActivities;

	public static List<Employee> employees;

	public List<Employee> employeesForCarrusel;

	public List<Comment> comments = new ArrayList<Comment>();

	private List<Task> tasks = new ArrayList<Task>();

	private Task selectedTask;

	private Employee selectedEmployee;

	private Activity selectedActivity;

	private CommentController commentController;

	private DataTable tasksTable;

	private String newComment;

	private int selectedProgress;

	private EmployeeController employeeController;

	private Map<String, Integer> ringPosition = new HashMap<String, Integer>();

	private int ringIndex = 0;

	public int getRingIndex() {
		return ringIndex;
	}

	public void setRingIndex(int ringIndex) {
		this.ringIndex = ringIndex;
	}

	@Inject
	public TasksTableBean(TaskController taskController,
			EmployeeController employeeController,
			CommentController commentController) {
		this.employeeController = employeeController;
		this.taskController = taskController;
		this.commentController = commentController;
		employees = employeeController.getEmployees();
		selectedActivity = new Activity();
		selectedTask = new Task();
		myTask = new Task();
		newComment = "";
		loadEmployeeMap(employees);
	}

	public void onEnter(ActionEvent actionEvent) {
		setCurrentUserInCarrusel();
	}

	public void init(ComponentSystemEvent event) {
		if (!FacesContext.getCurrentInstance().isPostback()) {
			setCurrentUserInCarrusel();
		}
	}

	private void setCurrentUserInCarrusel() {

		String username = employeeController.getCurrentUsername();
		Employee loggedIn = employeeController.getLoggedInUser(username);
		employeesForCarrusel = employeeController.getEmployees();
		// tengo que re-indexar porque las posiciones no son las mismas que
		// cuando entre
		loadEmployeeMap(employeesForCarrusel);
		int deletePosition = ringPosition.get(loggedIn.getUsername());

		if (deletePosition != 0) {
			Employee temp = employeesForCarrusel.get(0);
			employeesForCarrusel.remove(deletePosition);
			employeesForCarrusel.set(0, loggedIn);
			employeesForCarrusel.add(temp);
		}

		setSelectedEmployee(loggedIn);
	}

	private void loadEmployeeMap(List<Employee> employees2) {
		for (int i = 0; i < employees2.size(); i++) {
			Employee tmp = (Employee) employees2.get(i);
			ringPosition.put(tmp.getUsername(), i);

		}
	}

	public void deleteActivity(ActionEvent actionEvent) {
		if (selectedActivity == null || selectedActivity.getId() == 0) {
			FacesContext
					.getCurrentInstance()
					.addMessage(
							null,
							new FacesMessage(
									"Usted no ha seleccionado ninguna actividad. Por seguridad se requiere seleccionar primero la actividad antes de borrarla"));
			return;
		}
		activities.remove(selectedActivity);
		tasks = new ArrayList<Task>();
		comments = new ArrayList<Comment>();
		selectedTask = new Task();
		taskController.removeActivity(selectedActivity);
		FacesContext.getCurrentInstance().addMessage(
				null,
				new FacesMessage("La actividad " + selectedActivity.getName()
						+ " ha sido eliminada"));
		selectedActivity = new Activity();
	}

	public void newTask(ActionEvent actionEvent) {
		allActivities = taskController.getAllActivities();
		myTask.setEmployee(selectedEmployee);
		if (selectedActivity == null || selectedActivity.getId() == 0) {
			myTask.setActivity(allActivities.get(0));
			selectedActivity = allActivities.get(0);
		} else
			myTask.setActivity(selectedActivity);
	}

	public void newActivity(ActionEvent actionEvent) {
		selectedActivity = new Activity();
	}

	public void save(ActionEvent actionEvent) {

		DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
		taskController.save(myTask);
		String email = myTask.getEmployee().getEmail();
		String name = myTask.getName();
		String userName = employeeController.getCurrentUsername();
		try {
			Thread emailController = new Thread(new EmailController(email,
					name, dateFormat.format(myTask.getStartDate()),
					dateFormat.format(myTask.getFinishDate()), userName,
					myTask.getDescription(), 1));
			emailController.start();
		} catch (Exception exception) {
			System.out.println("No se pudo enviar mail para la tarea :"
					+ myTask.getName());
			FacesContext.getCurrentInstance().addMessage(
					null,
					new FacesMessage(FacesMessage.SEVERITY_WARN,
							"No se pudo enviar mail para la tarea :"
									+ myTask.getName(),
							"No se pudo enviar mail para la tarea :"
									+ myTask.getName()));
		}
		cleanVariables();
	}

	public void saveComment(ActionEvent actionEvent) {
		String username = employeeController.getCurrentUsername();
		Employee employee = employeeController.getEmployeeByUsername(username);
		// selectedTask.setEmployee(myTask.getEmployee());
		Comment comment = new Comment();
		comment.setText(newComment);
		// just returning for displaying with ajax
		int result = commentController.save(comment, selectedTask, employee,
				selectedProgress);
		selectedTask.getComments().add(comment);
		selectedActivity.setProgress(result);
		FacesContext.getCurrentInstance().addMessage(null,
				new FacesMessage("El comentario ha sido agregado"));
		newComment = "";
		selectedProgress = 0;
		Thread emailController = new Thread(new EmailController(selectedTask
				.getEmployee().getEmail(), selectedTask.getActivity()
				.getEmployeeCreator().getEmail(), comment, username, 0));
		emailController.start();
	}

	public void saveActivity(ActionEvent actionEvent) {
		taskController.saveActivity(selectedActivity);
		cleanVariables();

	}

	public void beforeEditActivity() {
		if (selectedActivity == null) {
			FacesContext.getCurrentInstance().addMessage(null,
					new FacesMessage("El comentario ha sido agregado"));
			selectedActivity = new Activity();

		}

	}

	public void cleanVariables() {
		myTask = new Task();
		selectedActivity = new Activity();
		selectedEmployee = new Employee();
		selectedTask = new Task();
		tasks = null;
		activities = null;
		newComment = "";
	}

	public void setSelectedEmployee(Employee selectedEmployee) {
		this.selectedEmployee = selectedEmployee;
		tasks = new ArrayList<Task>();
		selectedTask = new Task();
		selectedActivity = new Activity();
		String username = employeeController.getCurrentUsername();
		activities = taskController.getActivitiesToDisplayForEmployee(
				selectedEmployee, username);
	}

	public void handleSelectedEmployee(ActionEvent actionEvent) {
		selectedEmployee = (Employee) actionEvent.getComponent()
				.getAttributes().get("selectedEmployee");
		setSelectedEmployee(selectedEmployee);
	}

	public List<Activity> getActivities() {
		return activities;
	}

	public void showActivitiesForSelectedUser(ActionEvent actionEvent) {
		setSelectedEmployee(selectedEmployee);
	}

	
	
	public void showAllActivitiesWithTasksToBeApproved() {
		activities = taskController.getAllActivitiesWithTasksToBeApproved();
		List<Task> tasksToBeApproved = new ArrayList<Task>();
		for (Activity myActivity : activities) {
			for (Task task : myActivity.getTasks()) {
				if (task.getProgress() == 75) {
					tasksToBeApproved.add(task);
				}
			}
		}
		tasks = tasksToBeApproved;
		FacesContext.getCurrentInstance().addMessage(
				null,
				new FacesMessage(
						"Mostrando todas las actividades con tareas a aprobar "));
}

	
	public void showAllActivities() {
			activities = taskController.getAllActivities();
			FacesContext.getCurrentInstance().addMessage(
					null,
					new FacesMessage(
							"Mostrando todas las actividades "));
	}
	
	public void showAllActivitiesOrderByTaskDeadLine() {
		activities = taskController.getAllActivitiesOrderByTaskDeadLine();
	}
	
	public void showMyTasks(SelectEvent event) {
		Activity activity = (Activity) event.getObject();
		selectedActivity = activity;
		selectedTask = new Task();
		tasks = taskController.getTasksByActivityIdForEmployee(
				selectedActivity.getId(), selectedEmployee);
	}
	
	public void showMyTasks(ActionEvent event) {
		if (checkActivitySelection()) {
			Employee loggedInUser = employeeController
					.getLoggedInUser(employeeController.getCurrentUsername());
			tasks = taskController.getTasksByActivityIdForEmployee(
					selectedActivity.getId(), loggedInUser);
			FacesContext.getCurrentInstance().addMessage(
					null,
					new FacesMessage("Mostrando tareas de la actividad "
							+ selectedActivity.getName() + " para el usuario "
							+ loggedInUser.getFirstname() + " "
							+ loggedInUser.getLastname()));
		}
	}
	

	public void showTasksForActivity(SelectEvent event) {
		Activity activity = (Activity) event.getObject();
		selectedActivity = activity;
		selectedTask = new Task();

	}

	public void showTasksForActivity(ActionEvent event) {
		if (checkActivitySelection()) {

			tasks = taskController.getTasksByActivityId(selectedActivity
					.getId());
			FacesContext.getCurrentInstance().addMessage(
					null,
					new FacesMessage(
							"Mostrando todas las tareas de la actividad "
									+ selectedActivity.getName()));
		}

	}

	public void showFinishedTasks(ActionEvent event) {
		if (checkActivitySelection()) {
			tasks = taskController.getFinishedTasks(selectedActivity.getId());
			FacesContext.getCurrentInstance().addMessage(
					null,
					new FacesMessage(
							"Mostrando tareas finalizadas de la actividad "
									+ selectedActivity.getName()));
		}

	}

	public void showCurrentTasks(ActionEvent event) {
		if (checkActivitySelection()) {
			tasks = taskController.getCurrentTasks(selectedActivity.getId());
			FacesContext.getCurrentInstance().addMessage(
					null,
					new FacesMessage(
							"Mostrando tareas en progreso de la actividad "
									+ selectedActivity.getName()));
		}
	}


	private boolean checkActivitySelection() {
		if (selectedActivity == null || selectedActivity.getId() == 0) {
			FacesContext.getCurrentInstance().addMessage(
					null,
					new FacesMessage(FacesMessage.SEVERITY_WARN,
							"Usted no ha seleccionado ninguna actividad", ""));
			return false;
		}
		return true;
	}

	public void populateCommentsDialog(ActionEvent actionEvent) {
		for (Employee employee : employees) {
			if (employee.getId() == myTask.getEmployee().getId()) {
				selectedTask.setEmployee(employee);
			}
		}
		newComment = "";
		selectedTask.setProgress(0);
		RequestContext.getCurrentInstance().addPartialUpdateTarget(
				":form:slider");
	}

	public void showCommentsForTask() {
		selectedTask = (Task) tasksTable.getRowData();
		System.out.println("showCommentsForTask : "
				+ selectedTask.getEmployee().getFirstname());
		myTask.setEmployee(selectedTask.getEmployee());
		selectedTask.setComments(commentController
				.getCommentsForTask(selectedTask.getId()));
	}

	public void removeTask() {

		try {
			// delete it from DB
			taskController.remove(selectedTask);
			// delete it from UI
			tasks.remove(selectedTask);
			// Horrible hack! This is to reload the new progress for the
			// activity
			String username = employeeController.getCurrentUsername();
			activities = taskController.getActivitiesToDisplayForEmployee(
					selectedEmployee, username);

			FacesContext.getCurrentInstance().addMessage(
					null,
					new FacesMessage("La tarea " + selectedTask.getName()
							+ " ha sido borrada."));
			// commentsPanel should be empty!
			selectedTask = new Task();
		} catch (Exception e) {
			System.out.println(e.getMessage());
			FacesContext.getCurrentInstance().addMessage(
					null,
					new FacesMessage(FacesMessage.SEVERITY_WARN,
							"Por favor elija una tarea antes de eliminarla",
							"Por favor elija una tarea antes de eliminarla"));
		}

	}

	public void setActivities(List<Activity> activities) {
		this.activities = activities;
	}

	public Activity getSelectedActivity() {
		return selectedActivity;
	}

	public void setSelectedActivity(Activity selectedActivity) {
		this.selectedActivity = selectedActivity;
	}

	public void cleanTasks(UnselectEvent event) {
	}

	public List<Task> getTasks() {
		return tasks;
	}

	public void setTasks(List<Task> tasks) {
		this.tasks = tasks;
	}

	public List<Activity> getAllActivities() {
		return allActivities;
	}

	public Task getMyTask() {
		return myTask;
	}

	public void setMyTask(Task myTask) {
		this.myTask = myTask;
	}

	public List<Employee> getEmployees() {
		return employees;
	}

	public Task getSelectedTask() {
		return selectedTask;
	}

	public void setSelectedTask(Task selectedTask) {
		this.selectedTask = selectedTask;
	}

	public Employee getSelectedEmployee() {
		return selectedEmployee;
	}

	public DataTable getTasksTable() {
		return tasksTable;
	}

	public void setTasksTable(DataTable tasksTable) {
		this.tasksTable = tasksTable;
	}

	public List<Comment> getComments() {
		return comments;
	}

	public void setComments(List<Comment> comments) {
		this.comments = comments;
	}

	public String getNewComment() {
		return newComment;
	}

	public void setNewComment(String newComment) {
		this.newComment = newComment;
	}

	public int getSelectedProgress() {
		return selectedProgress;
	}

	public void setSelectedProgress(int selectedProgress) {
		this.selectedProgress = selectedProgress;
	}

	public void finishDateAsString(ActionEvent actionEvent) {
		DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
		SelectOneMenu selectOneMenuActivities = (SelectOneMenu) actionEvent
				.getComponent().getAttributes().get("selectOneMenuActivities");
		String activityString = (String) selectOneMenuActivities
				.getSubmittedValue();
		Activity activity = DisplayHelperBean.findSelectedActivity(
				activityString, allActivities);
		String startDate = dateFormat.format(myTask.getActivity()
				.getStartDate());
		String finishDate = dateFormat.format(activity.getFinishDate());
		FacesContext.getCurrentInstance().addMessage(
				null,
				new FacesMessage(FacesMessage.SEVERITY_INFO, "La actividad "
						+ activity.getName() + " comienza el " + startDate
						+ " y finaliza el " + finishDate, ""));
		;
	}

	public List<Employee> getEmployeesForCarrusel() {
		return employeesForCarrusel;
	}

	public void setEmployeesForCarrusel(List<Employee> employeesForCarrusel) {
		this.employeesForCarrusel = employeesForCarrusel;
	}

}
